package nayasis.common.executor;

import java.io.IOException;

import nayasis.common.exception.unchecked.CommandLineException;

/**
 * OS에서 명령어(Command Line)를 수행하는 유틸리티 클래스
 *
 * @author nayasis
 *
 */
public abstract class CommandLine {

	/**
	 * Command 명령어를 수행한다.
	 * 
	 * @param commandLine 명령어
	 */
	public static void exec( String commandLine ) {
		exec( getCommand(commandLine), null, null );
	}

	/**
	 * 명령어를 수행한다.
	 * 
	 * @param commandLine	명령어
	 * @param outputMessage	프로세스에서 출력한 메세지를 담을 객체
	 */
	public static void exec( String commandLine, StringBuffer outputMessage ) {
		exec( getCommand(commandLine), outputMessage, outputMessage );
	}
	

	private static String[] getCommand( String commandLine ) {
		return ( commandLine == null ) ? null : commandLine.split( " " );
	}
	
	/**
	 * 명령어를 수행한다.
	 * 
	 * @param commandLine	명령어
	 * @param outputMessage	프로세스에서 출력한 메세지를 담을 객체
	 * @param errorMessage	프로세스에서 출력한 에러 메세지를 담을 객체
	 */
	public static void exec( String[] commandLine, StringBuffer outputMessage, StringBuffer errorMessage ) {

		if( commandLine == null ) {
			throw new CommandLineException( "수행할 명령어가 없습니다." );
		}

		Process process = null;

		try {

			process = Runtime.getRuntime().exec( commandLine );

			Thread outMsgThread = null;
			Thread errMsgThread = null;

			if( outputMessage == null ) {
				outMsgThread = new ProcessThread( process.getInputStream() );
				
			} else {
				outMsgThread = new ProcessOutputThread( process.getInputStream(), outputMessage );
				
			}

			if( errorMessage == null ) {
				errMsgThread = new ProcessThread( process.getErrorStream() );
				
			} else {
				errMsgThread = new ProcessOutputThread( process.getErrorStream(), errorMessage );
				
			}

			outMsgThread.start();
			errMsgThread.start();

			process.waitFor();

		} catch ( IOException | InterruptedException e ) {

			throw new CommandLineException( e, "명령어(@)실행 중 에러가 발생하였습니다.", commandLine.toString() );

		} finally {

			if( process != null ) process.destroy();

		}

	}

}
